#ifndef TCP_HEADERS
#define TCP_HEADERS
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdint.h>
#include <errno.h>
#endif

#ifndef STRING_H
#define STRING_H
#include <string>
#endif

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define null 0

/* TCP Connection Implementation */
class ProxyConnection {
	sockaddr_in host_to_addr(std::string _host, unsigned short _port);
public:
	int sock;
	sockaddr_in addr;
	unsigned short port;
	ProxyConnection() { }
	ProxyConnection(std::string _host, unsigned short _port) {
		sock = socket(AF_INET, SOCK_STREAM, 0);
		addr = host_to_addr(_host, _port);
		if(addr.sin_addr.s_addr == null) {
			// Failed to get host info
			sock = null;
		}
		else {
			int result = connect(sock, (sockaddr*)&addr, sizeof(sockaddr_in));
			if (result < 0) {
				std::string err_msg = "";
				if(errno == ECONNREFUSED) {
					err_msg = "Connection refused.";
				}
				else if(errno == EISCONN) {
					err_msg = "Socket is already connected.";
				}
				else if(errno == ETIMEDOUT) {
					err_msg = "Connection timed out.";
				}
				else if(errno == EHOSTUNREACH) {
					err_msg = "No route to host.";
				}
				else if(errno == ENETUNREACH) {
					err_msg = "No route to network.";
				}
				else {
					printf("%d\n", errno);
					err_msg = "Could not connect to host.";
				}
				printf("Error: %s\n", err_msg.c_str());
				sock = 0;
			}
		}
	}

	std::string send_url(std::string msg);

	void close_connection();
};

